package gittexn.utils;

import cn.hutool.core.util.XmlUtil;
import cn.hutool.http.HttpUtil;
import gittexn.config.WeChatConfig;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.Iterator;
import java.util.Map;
import java.util.SortedMap;
import java.util.TreeMap;

public class WeChatPay {

    /**
     * @Description NATIVE支付模式（二维码网页扫码支付）
     */
    public static String getNative(String body,String totalFee) throws Exception {
        //账号信息
        String appid = WeChatConfig.APPID;
        String mch_id = WeChatConfig.MCHID;
        String key = WeChatConfig.APIKEY;

        //微信支付成功之后的回调地址【注意：当前回调地址必须是公网能够访问的地址】
        String notify_url = WeChatConfig.WECHAT_NOTIFY_URL_PC;
        String ufdoder_url = WeChatConfig.UFDODER_URL;
        String trade_type = "NATIVE";
        String out_trade_no = PayForUtil.getOrderNo();

        //请求参数封装
        SortedMap<Object, Object> packageParams = new TreeMap<Object, Object>();
        packageParams.put("appid", appid);
        packageParams.put("mch_id", mch_id);
        // 随机字符串
        packageParams.put("nonce_str", "nonce"+out_trade_no);
        // 支付的商品名称
        packageParams.put("body", body);
        // 商户订单号【备注：每次发起请求都需要随机的字符串，否则失败。】
        packageParams.put("out_trade_no",out_trade_no);
        // 支付金额
        packageParams.put("total_fee", totalFee);
        // 客户端主机
        packageParams.put("spbill_create_ip", PayForUtil.localIp());
        packageParams.put("notify_url", notify_url);
        packageParams.put("trade_type", trade_type);

        // 获取签名
        String sign = PayForUtil.createSign(packageParams, key);
        packageParams.put("sign", sign);

        // 将请求参数转换成String类型
        String requestXML = XmlUtil.mapToXmlStr(packageParams, "xml");
        System.err.println("请求报文：-----------------------------------");
        System.err.println(requestXML);

        // 解析请求之后的xml参数并且转换成String类型
        String resXml= HttpUtil.post(ufdoder_url, requestXML);
        System.err.println("应答报文：-----------------------------------");
        System.err.println(resXml);

        return resXml;
    }

    /**
     * @Description 支付回调
     */
    public static void notify(HttpServletRequest request, HttpServletResponse response) throws Exception {
        // 读取回调数据
        InputStream inputStream;
        StringBuffer sb = new StringBuffer();
        inputStream = request.getInputStream();
        String s;
        BufferedReader in = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"));
        while ((s = in.readLine()) != null) {
            sb.append(s);
        }
        in.close();
        inputStream.close();

        // 解析xml成map
        Map<String, Object> m= XmlUtil.xmlToMap(sb.toString());
        // 过滤空 设置 TreeMap
        SortedMap<Object, Object> packageParams = new TreeMap<Object, Object>();
        Iterator<String> it = m.keySet().iterator();
        while (it.hasNext()) {
            String parameter = it.next();
            Object parameterValue = m.get(parameter);
            String v = "";
            if (null != parameterValue) {
                v = parameterValue.toString().trim();
            }
            packageParams.put(parameter, v);
        }

        // 微信支付的API密钥
        String key = WeChatConfig.APIKEY;
        // 判断签名是否正确
        if (PayForUtil.isTenpaySign(packageParams, key)) {
            String resXml = "";
            if ("SUCCESS".equals((String) packageParams.get("result_code"))) {
                System.err.println("--------------------------------------------");
                System.err.println("支付回调成功。。。可在此处执行业务逻辑。。。");
                System.err.println("--------------------------------------------");

                // 支付成功,执行自己的业务逻辑开始
                String app_id = (String) packageParams.get("appid");
                String mch_id = (String) packageParams.get("mch_id");
                String openid = (String) packageParams.get("openid");
                // 是否关注公众号
                String is_subscribe = (String) packageParams.get("is_subscribe");
                // 附加参数【商标申请_0bda32824db44d6f9611f1047829fa3b_15460】--【业务类型_会员ID_订单号】
                String attach = (String) packageParams.get("attach");
                String out_trade_no = (String) packageParams.get("out_trade_no");
                String total_fee = (String) packageParams.get("total_fee");
                // 微信支付订单号
                String transaction_id = (String) packageParams.get("transaction_id");
                // 支付完成时间
                String time_end = (String) packageParams.get("time_end");

                // 通知微信.异步确认成功.必写.不然会一直通知后台.八次之后就认为交易失败了.
                resXml = "<xml>" + "<return_code><![CDATA[SUCCESS]]></return_code>"
                        + "<return_msg><![CDATA[OK]]></return_msg>" + "</xml> ";
            } else {
                System.err.println("支付失败,错误信息：" + packageParams.get("err_code"));

                resXml = "<xml>" + "<return_code><![CDATA[FAIL]]></return_code>"
                        + "<return_msg><![CDATA[报文为空]]></return_msg>" + "</xml> ";
            }
            response.getWriter().write(resXml);
        } else {
            System.err.println("通知签名验证失败");
        }
    }
}
